﻿///*
// * Created by SharpDevelop.
// * User: Lance.zhou
// * Date: 11/29/2012
// * Time: 4:19 PM
// * 
// * 
// */
//using System;
//using System.Collections.Concurrent;
//using System.IO;
//using System.IO.MemoryMappedFiles;
//using System.Threading;
//using System.Threading.Tasks;
//
//namespace chromium.Cache
//{
//	/// <summary>
//	/// Description of MemoryMappedFileCache.
//	/// </summary>
//	public class MemoryMappedFileCache
//	{
//		private long capcity;
//		private long offset;
//		private volatile bool shrinking; 
//		private MemoryMappedFile backend;
//		private ConcurrentDictionary<string,Stream> cacheItemTemps =new ConcurrentDictionary<string,Stream>();
//		private ConcurrentDictionary<string,CacheItem> cacheItems =new ConcurrentDictionary<string,CacheItem>();
//			
//		public MemoryMappedFileCache()
//		{
//			if(!File.Exists("cache.rdb"))
//			{
//				using(FileStream fs = new FileStream("cache.rdb",FileMode.Create))
//				{
//					fs.SetLength(capcity);
//				}
//			}
//			backend = new MemoryMappedFile("cache.rdb");
//		}
//		
//		public async Task<bool> CopyTo(string key, Stream to)
//		{
//			CacheItem item;
//			if(cacheItems.TryGetValue(key, out item))
//			{
//				using(MemoryMappedViewStream stream= backend.CreateViewStream(item.Offset,item.Size))
//				{
//					await stream.CopyToAsync(to);
//				}
//				if(item.Expired)
//				{
//					cacheItems.TryRemove(key, out item);
//				}
//				return true;
//			}
//			return false;
//		}
//		
//		public async void AddCache(string key, Stream from)
//		{
//			if(shrinking || offset + from.Length > capcity)
//			{
//				if(!shrinking) {
//					shrinking = true;
//					DoShrinking();
//				}
//				cacheItemTemps[key] = from;
//				return;
//			}
//			long newOffset = Interlocked.Add(ref offset, from.Length);
//			
//			CacheItem item = new CacheItem(key,newOffset - from.Length, from.Length);
//			
//			using(MemoryMappedViewStream to= backend.CreateViewStream(item.Offset,item.Size))
//			{
//				await from.CopyToAsync(to);
//				cacheItems[key] = item;
//			}
//		}
//		
//		private async void DoShrinking()
//		{
//			FileStream tempFs= new FileStream("temp.rdb", FileMode.Create);
//			tempFs.SetLength(capcity);
//			foreach(var kv in cacheItems)
//			{
//				if(!kv.Value.Expired)
//				{
//					using(MemoryMappedViewStream stream= backend.CreateViewStream(item.Offset,item.Size))
//					{
//						await stream.CopyToAsync(fs);
//					}
//				}
//			}
//		}
//	}
//}
